function spawnMob(x,y)
	
	local newMob = {}

	newMob["x"] = x
	newMob["y"] = y

	newMob["alerted"] = false
	newMob["turnsAlerted"] = 0

	newMob["alive"] = true
	newMob["health"] = 100

	newMob["isMoving"] = false
	newMob["heading"] = genHeading()

	newMob["isTurning"] = false
	newMob["targetHeading"] = heading.value


	local dieRoll = math.random(math.min(getLevel(),3))

	if (dieRoll == 1) then  -- manshonyagger
		newMob["mobID"] = "my"
		newMob["desc"] = "manshonyagger"

		newMob["level"] = 1
		newMob["armour"] = 1
		newMob["range"] = 6

		newMob["meleeDamage"] = 2
		newMob["rangedDamage"] = 2

	elseif (dieRoll == 2) then

		newMob["mobID"] = "rob"
		newMob["desc"] = "assassin droid"

		newMob["level"] = 2
		newMob["armour"] = 2
		newMob["range"] = 7

		newMob["meleeDamage"] = 2
		newMob["rangedDamage"] = 4

	elseif (dieRoll == 3) then

		newMob["mobID"] = "jug"
		newMob["desc"] = "juggernaught"

		newMob["level"] = 3
		newMob["armour"] = 3
		newMob["range"] = 5

		newMob["meleeDamage"] = 5
		newMob["rangedDamage"] = 3

	end

	activeMobs = {next = activeMobs, value = newMob }
end

function alertAllMobs()
	local mobList = activeMobs
	while mobList do
		if (mobList.value.alive == true and mobList.value.alerted == false ) then alertMob(mobList.value) end
		mobList = mobList.next
	end
end

function alertMob(mob)
	mob.alerted = true
	addConsoleMessage("You alerted a ".. mob.desc .."!", "red")

	-- cancel mob movements!
	mob.isMoving = false
	mob.isTurning = false
end

function mobAI(mob)

	if (outofRange(mob.x,mob.y) == true) then return end


	local mobMoved = false
	local mobTurned = false

	-- move Mob
	if (mob.isMoving == true) then
		local tx =  mob.x+mob.heading.value[1]
		local ty =	mob.y+mob.heading.value[2]

		if (isMoveBlocked(tx,ty) == false) then
			mob.x = tx
			mob.y = ty

			mobMoved = true
		end
		mob.isMoving = false
	end

	-- turn mob
	if (mob.isTurning == true) then
		mob.heading = mob.targetHeading
		mob.isTurning = false
		mobTurned = true
	end

	-- Check for alert
	if (mob.alerted == false) then
		if  (ComputeFOV({mob.x,mob.y}, mob.heading.value, characterLoc, mob.range, false) == true) then
			alertMob(mob)
			mob.turnsAlerted = mob.turnsAlerted + 1
			return
		end
	end

	-- If alerted,
	if (mob.alerted == true) then

		mob.turnsAlerted = mob.turnsAlerted + 1

		-- first check to see if player is still visible
		if  (ComputeFOV({mob.x,mob.y}, mob.heading.value, characterLoc, mob.range, true) == true) then

			if (mobMoved == false and mobTurned == false and mob.turnsAlerted > 1 ) then -- if no turn or move, hit the player!
				mobHitPlayer(mob)
				return
			end

			return

		else -- if not visible

			-- first check if a single move along the current heading fixes it ( to avoid rotating to hit )
			-- local testPos = {mob.x + mob.heading.value[1], mob.y + mob.heading.value[2]}
			-- if (ComputeFOV(testPos, mob.heading.value, characterLoc, mob.range, true) == true) then
			-- 	mob.isMoving = true
			-- 	return
			-- end

			-- cant see target, see if you can rotate
			local tHeading = getBestHeading({mob.x,mob.y}, mob.heading, characterLoc, mob.range)
			if (tHeading ~= nil) then 
				mob.isTurning = true
				mob.targetHeading = tHeading
				return
			end


			-- still can't see, start pathfinding!
			 local pathToTarget = getPath({mob.x,mob.y}, characterLoc)

			-- no path
			if (pathToTarget == nil) then 
				mob.alerted = false 
				addConsoleMessage("DEBUG: Alert Lost", "yellow")
				return
			end

			-- (COMMENT COMMENT) diff between mob location and next point in path
			-- note that when alerted, mobs can move and turn in one tick
			-- (otherwise the player can easily run away)
			local targetDiff = { x = pathToTarget[2].x - mob.x, y = pathToTarget[2].y - mob.y }

			-- if the targetdiff to the next path element is the same as the heading, move out!
			if (targetDiff.x == mob.heading.value[1] and targetDiff.y == mob.heading.value[2] ) then
				mob.isMoving = true

				-- set up turn for next block
				if (pathToTarget[3] ~= nil ) then
					followDiff = { x = pathToTarget[3].x - pathToTarget[2].x, y = pathToTarget[3].y - pathToTarget[2].y }

					-- Don't need to turn
					if (followDiff.x == targetDiff.x and followDiff.y == targetDiff.y)
						then return end

					tHeading = mob.heading
					for i=1,9,1 do
						-- if next targetDiff matches, set turn
						if (followDiff.x == tHeading.value[1] and followDiff.y == tHeading.value[2] ) then
							mob.isTurning = true
							mob.targetHeading = tHeading
							return
						end
						tHeading = tHeading.next
					end
				end

				-- return successful
				return
			else --otherwise, need to perform a turn right now
				tHeading = mob.heading
				for i=1,9,1 do
					if (targetDiff.x == tHeading.value[1] and targetDiff.y == tHeading.value[2] ) then
						--mob.isTurning = true
						--mob.targetHeading = tHeading
						mob.heading = tHeading
						mob.isMoving = true
						return
					end
					tHeading = tHeading.next
				end

			end 

			


		end


		return
	end

	--Otherwise, random movement

	-- set up move order
	if (math.random(3) == 1) then
		local tx = mob.x + mob.heading.value[1]
		local ty = mob.y + mob.heading.value[2]

		if (isMoveBlocked(tx,ty) == false) then
			mob.isMoving = true
		end
	end

	if (math.random(3) == 1) then
	 	mob.isTurning = true 

	 	mob.targetHeading = mob.heading
	 	for i=1,math.random(9),1 do 
	 		mob.targetHeading = mob.targetHeading.next
	 	end

	 	if (mob.targetHeading == mob.heading) then mob.isTurning = false end
	end

end


function killMob(targetMob)
	targetMob.alive = false

	addConsoleMessage("The " .. targetMob.desc .. " collapses to the floor, deactivated ", "green")

	characterKills = characterKills + 1

	-- drop chance!
	local dropAmmo = math.random(200)

	if (dropAmmo <= dropRate[targetMob.level]) then
		dropItem(gameItems.ammo[math.random(targetMob.level)],{targetMob.x,targetMob.y}) --  drop up to current level
	end

	local dropUtil = math.random(90)
	if (dropUtil <= dropRate[targetMob.level]) then
		dropItem(gameItems.utils[math.random(#gameItems.utils)],{targetMob.x,targetMob.y})
	end

	-- roll again for health
	if (characterHealth <= 35) then 
		local dropUtil = math.random(80)
		if (dropUtil <= dropRate[targetMob.level]) then
			dropItem(gameItems.utils[math.random(#gameItems.utils)],{targetMob.x,targetMob.y})
		end
	end

	-- roll again for heat!
	if (characterHeat < 50 ) then
 		if (math.random(80) < dropRate[targetMob.level]) then
 			dropItem(gameItems.utils[2],{targetMob.x,targetMob.y})
 		end
 	elseif (characterHeat == 0 ) then
 		dropItem(gameItems.utils[2],{targetMob.x,targetMob.y})
 	end

 	-- roll again for armour!
 	if (math.random(200) < dropRate[targetMob.level]) then
 		dropItem(gameItems.armour[math.random(math.min(targetMob.level,4))],{targetMob.x,targetMob.y})
 	end

 	 -- roll again for weapons!
 	if (math.random(300) < dropRate[targetMob.level]) then
 		dropItem(gameItems.guns[targetMob.level],{targetMob.x,targetMob.y})
 	end
 	 if (math.random(300) < dropRate[targetMob.level]) then
 		dropItem(gameItems.melee[targetMob.level],{targetMob.x,targetMob.y})
 	end


	return
end

function getMobsAlive()

	local mobList = activeMobs
	local count = 0
	while (mobList) do
		if (mobList.value.alive == true) then count = count+1 end
		mobList = mobList.next
	end

	return count
end

function getDamageFactor(damage)

	for i,v in ipairs(damageFactor) do
		if (damage <= v) then return i end
	end

	return #damageFactor
end


function playerHitMob(weaponUsed,targetMob)

	local damageDealt =  weaponDamage[weaponUsed.damage]*armourPower[targetMob.armour]
	if (targetMob.alerted == false) then
	 	damageDealt = 2*damageDealt 
	end

	local output = ""

	if (weaponUsed.itemtype == "gun") then
		output = "Your fire your " .. weaponUsed.desc .. " at the " .. targetMob.desc
		if (targetMob.alerted == false) then output = output .. " in a surprise attack" end
	else
		output = "Your blow with the ".. weaponUsed.desc .." strikes the " .. targetMob.desc
		if (targetMob.alerted == false) then output = output .. " unawares" end
	end


	output = output .. ", dealing " .. damageString[getDamageFactor(damageDealt)] .. " damage " 
	addConsoleMessage(output, "yellow")


	targetMob.health = targetMob.health - damageDealt
	if (targetMob.health <= 0) then killMob(targetMob) return end

	-- ensure target is now alerted
	if (targetMob.alerted == false) then alertMob(targetMob) end
end

function mobHitPlayer(mob)

	local melee = true

	-- ranged attack
	if (   (math.abs( mob.x - characterLoc[1] ) > 1)
		or (math.abs( mob.y - characterLoc[2] ) > 1) )  then
			melee = false
	end

	local damageDealt =  0

	if (melee == true) then
		damageDealt = playerDamageFactor*weaponDamage[mob.meleeDamage]*armourPower[characterArmour]
	else
		damageDealt = playerDamageFactor*weaponDamage[mob.rangedDamage]*armourPower[characterArmour]
	end


	local output = ""

	if (melee == true) then
		output = "The " .. mob.desc .. " strikes you with a melee attack"
	else
		output = "The " .. mob.desc .. " fires it's weapon at you"
	end

	output = output .. ", causing " .. damageString[getDamageFactor(damageDealt)] .. " damage " 
	addConsoleMessage(output, "red")


	characterHealth = characterHealth - damageDealt

	if (characterHealth <= 0) then killPlayer("were killed by a " .. mob.desc) end
end



